﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.Election.KingdomPolicyDecision
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.Election
{
  public class KingdomPolicyDecision : KingdomDecision
  {
    [SaveableField(200)]
    public readonly PolicyObject Policy;
    [SaveableField(203)]
    private bool _isInvertedDecision;
    [SaveableField(202)]
    private List<PolicyObject> _kingdomPolicies;

    internal static void AutoGeneratedStaticCollectObjectsKingdomPolicyDecision(
      object o,
      List<object> collectedObjects)
    {
      ((KingdomDecision) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      collectedObjects.Add((object) this.Policy);
      collectedObjects.Add((object) this._kingdomPolicies);
    }

    internal static object AutoGeneratedGetMemberValuePolicy(object o)
    {
      return (object) ((KingdomPolicyDecision) o).Policy;
    }

    internal static object AutoGeneratedGetMemberValue_isInvertedDecision(object o)
    {
      return (object) ((KingdomPolicyDecision) o)._isInvertedDecision;
    }

    internal static object AutoGeneratedGetMemberValue_kingdomPolicies(object o)
    {
      return (object) ((KingdomPolicyDecision) o)._kingdomPolicies;
    }

    public KingdomPolicyDecision(Clan proposerClan, PolicyObject policy, bool isInvertedDecision = false)
      : base(proposerClan)
    {
      this.Policy = policy;
      this._isInvertedDecision = isInvertedDecision;
      this._kingdomPolicies = new List<PolicyObject>((IEnumerable<PolicyObject>) this.Kingdom.ActivePolicies);
    }

    public override bool IsAllowed()
    {
      return Campaign.Current.Models.KingdomDecisionPermissionModel.IsPolicyDecisionAllowed(this.Policy);
    }

    public override int GetProposalInfluenceCost()
    {
      return Campaign.Current.Models.DiplomacyModel.GetInfluenceCostOfPolicyProposalAndDisavowal(this.ProposerClan);
    }

    public override TextObject GetGeneralTitle() => this.Policy.Name;

    public override TextObject GetSupportTitle()
    {
      TextObject supportTitle = !this._isInvertedDecision ? new TextObject("{=iiH5gKzE}Vote for {POLICY_NAME}") : new TextObject("{=XGcST2dB}Vote to disavow {POLICY_NAME}");
      supportTitle.SetTextVariable("POLICY_NAME", this.Policy.Name);
      return supportTitle;
    }

    public override TextObject GetChooseTitle()
    {
      TextObject chooseTitle = !this._isInvertedDecision ? new TextObject("{=!}{POLICY_NAME}") : new TextObject("{=9DaDtQbo}Disavow {POLICY_NAME}");
      chooseTitle.SetTextVariable("POLICY_NAME", this.Policy.Name);
      return chooseTitle;
    }

    public override TextObject GetSupportDescription()
    {
      TextObject supportDescription = !this._isInvertedDecision ? new TextObject("{=jFOva44m}{FACTION_LEADER} proposes the policy of {POLICY_NAME}. You can pick your stance regarding this decision.") : new TextObject("{=ZPv3uCOb}{FACTION_LEADER} proposes disavowing the policy of {POLICY_NAME}. You can pick your stance regarding this decision.");
      supportDescription.SetTextVariable("FACTION_LEADER", this.DetermineChooser().Leader.Name);
      supportDescription.SetTextVariable("POLICY_NAME", this.Policy.Name);
      return supportDescription;
    }

    public override TextObject GetChooseDescription()
    {
      TextObject chooseDescription = !this._isInvertedDecision ? new TextObject("{=0EqPRs21}As {?IS_FEMALE}queen{?}king{\\?} you must decide whether to enforce the policy of {POLICY_NAME}.") : new TextObject("{=1AU2jnNV}As {?IS_FEMALE}queen{?}king{\\?} you must decide whether to disavow the policy of {POLICY_NAME}.");
      chooseDescription.SetTextVariable("IS_FEMALE", this.DetermineChooser().Leader.IsFemale ? 1 : 0);
      chooseDescription.SetTextVariable("POLICY_NAME", this.Policy.Name);
      return chooseDescription;
    }

    public override IEnumerable<DecisionOutcome> DetermineInitialCandidates()
    {
      yield return (DecisionOutcome) new KingdomPolicyDecision.PolicyDecisionOutcome(true);
      yield return (DecisionOutcome) new KingdomPolicyDecision.PolicyDecisionOutcome(false);
    }

    public override Clan DetermineChooser() => this.Kingdom.RulingClan;

    public float CalculateSupport(Clan clan)
    {
      return this.DetermineSupport(clan, (DecisionOutcome) new KingdomPolicyDecision.PolicyDecisionOutcome(true));
    }

    protected override bool ShouldBeCancelledInternal()
    {
      return !this._isInvertedDecision ? this.Kingdom.ActivePolicies.Contains(this.Policy) : !this.Kingdom.ActivePolicies.Contains(this.Policy);
    }

    public override float DetermineSupport(Clan clan, DecisionOutcome possibleOutcome)
    {
      KingdomPolicyDecision.PolicyDecisionOutcome policyDecisionOutcome = possibleOutcome as KingdomPolicyDecision.PolicyDecisionOutcome;
      float num1 = 0.1f;
      float num2 = 0.1f;
      float num3 = 0.1f;
      if (clan.Kingdom != null && clan.Kingdom.RulingClan == clan)
      {
        ++num2;
        num3 -= 1.5f;
        num1 -= 0.4f;
      }
      else if (clan.IsMinorFaction)
      {
        ++num1;
        num3 -= 1.5f;
        num2 -= 0.3f;
      }
      else if (clan.Tier >= 3)
      {
        num1 -= 1.3f;
        num3 += (float) clan.Tier * 0.2f;
        num2 -= 1.3f;
      }
      else if (clan.Tier == 2)
      {
        num2 -= 0.1f;
        num3 += 0.4f;
        num1 -= 0.5f;
      }
      CultureObject culture = clan.Culture;
      float num4 = (float) ((double) this.Policy.EgalitarianWeight * (double) (num1 + (float) (0.60000002384185791 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Egalitarian) - 0.89999997615814209 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Oligarchic))) + (double) this.Policy.OligarchicWeight * (double) (num3 + (float) (0.60000002384185791 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Oligarchic) - 0.89999997615814209 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Egalitarian) - 0.5 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Authoritarian))) + (double) this.Policy.AuthoritarianWeight * (double) (num2 + (float) (0.800000011920929 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Authoritarian) - 1.2999999523162842 * (double) clan.Leader.GetTraitLevel(DefaultTraits.Oligarchic))));
      if (this._isInvertedDecision)
        num4 = -num4;
      float num5 = !policyDecisionOutcome.ShouldDecisionBeEnforced ? -100f : 60f;
      return num4 * num5;
    }

    public override void DetermineSponsors(MBReadOnlyList<DecisionOutcome> possibleOutcomes)
    {
      foreach (DecisionOutcome possibleOutcome in (List<DecisionOutcome>) possibleOutcomes)
      {
        if (((KingdomPolicyDecision.PolicyDecisionOutcome) possibleOutcome).ShouldDecisionBeEnforced)
          possibleOutcome.SetSponsor(this.ProposerClan);
        else
          this.AssignDefaultSponsor(possibleOutcome);
      }
    }

    public override void ApplyChosenOutcome(DecisionOutcome chosenOutcome)
    {
      bool decisionBeEnforced = ((KingdomPolicyDecision.PolicyDecisionOutcome) chosenOutcome).ShouldDecisionBeEnforced;
      if (decisionBeEnforced && !this._isInvertedDecision)
      {
        this.Kingdom.AddPolicy(this.Policy);
      }
      else
      {
        if (!decisionBeEnforced || !this._isInvertedDecision)
          return;
        this.Kingdom.RemovePolicy(this.Policy);
      }
    }

    public override TextObject GetChosenOutcomeText(
      DecisionOutcome chosenOutcome,
      KingdomDecision.SupportStatus supportStatus,
      bool isShortVersion = false)
    {
      TextObject chosenOutcomeText = ((KingdomPolicyDecision.PolicyDecisionOutcome) chosenOutcome).ShouldDecisionBeEnforced && !this._isInvertedDecision || !((KingdomPolicyDecision.PolicyDecisionOutcome) chosenOutcome).ShouldDecisionBeEnforced && this._isInvertedDecision ? (this._kingdomPolicies.Contains(this.Policy) ? new TextObject("{=jnYwiCAz}The {KINGDOM} will continue {POLICY_DESCRIPTION} ({POLICY}). {POLICY_SUPPORT}") : new TextObject("{=Lbs2bNlg}The {KINGDOM} will start {POLICY_DESCRIPTION} ({POLICY}). {POLICY_SUPPORT}")) : (!this._kingdomPolicies.Contains(this.Policy) ? new TextObject("{=faUooB7V}The {KINGDOM} will not be {POLICY_DESCRIPTION} ({POLICY}). {POLICY_SUPPORT}") : new TextObject("{=2BVDp7Tg}The {KINGDOM} will stop {POLICY_DESCRIPTION} ({POLICY}). {POLICY_SUPPORT}"));
      chosenOutcomeText.SetTextVariable("KINGDOM", this.Kingdom.InformalName);
      chosenOutcomeText.SetTextVariable("POLICY", this.Policy.Name);
      chosenOutcomeText.SetTextVariable("POLICY_DESCRIPTION", this.Policy.LogEntryDescription);
      if (isShortVersion || this.IsSingleClanDecision())
      {
        chosenOutcomeText.SetTextVariable("POLICY_SUPPORT", TextObject.Empty);
      }
      else
      {
        chosenOutcomeText.SetTextVariable("POLICY_SUPPORT", "{=bqEO389P}This decision caused a split in the council.");
        if (supportStatus == KingdomDecision.SupportStatus.Majority)
          chosenOutcomeText.SetTextVariable("POLICY_SUPPORT", "{=3W67kdtc}This decision had the support of the council.");
        if (supportStatus == KingdomDecision.SupportStatus.Minority)
          chosenOutcomeText.SetTextVariable("POLICY_SUPPORT", "{=b6MgRYlM}This decision was opposed by most of the council.");
      }
      return chosenOutcomeText;
    }

    public override DecisionOutcome GetQueriedDecisionOutcome(
      MBReadOnlyList<DecisionOutcome> possibleOutcomes)
    {
      return possibleOutcomes.FirstOrDefault<DecisionOutcome>((Func<DecisionOutcome, bool>) (t => ((KingdomPolicyDecision.PolicyDecisionOutcome) t).ShouldDecisionBeEnforced));
    }

    public override TextObject GetSecondaryEffects() => this.Policy.SecondaryEffects;

    public override void ApplySecondaryEffects(
      MBReadOnlyList<DecisionOutcome> possibleOutcomes,
      DecisionOutcome chosenOutcome)
    {
    }

    public class PolicyDecisionOutcome : DecisionOutcome
    {
      internal static void AutoGeneratedStaticCollectObjectsPolicyDecisionOutcome(
        object o,
        List<object> collectedObjects)
      {
        ((DecisionOutcome) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
      {
        base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      }

      internal static object AutoGeneratedGetMemberValueShouldDecisionBeEnforced(object o)
      {
        return (object) ((KingdomPolicyDecision.PolicyDecisionOutcome) o).ShouldDecisionBeEnforced;
      }

      [SaveableProperty(200)]
      public bool ShouldDecisionBeEnforced { get; private set; }

      public override TextObject GetDecisionTitle()
      {
        TextObject decisionTitle = new TextObject("{=kakxnaN5}{?SUPPORT}Yes{?}No{\\?}");
        decisionTitle.SetTextVariable("SUPPORT", this.ShouldDecisionBeEnforced ? 1 : 0);
        return decisionTitle;
      }

      public override TextObject GetDecisionDescription()
      {
        return this.ShouldDecisionBeEnforced ? new TextObject("{=pWyxaauF}We support this proposal") : new TextObject("{=BktSNgY4}We oppose this proposal");
      }

      public override string GetDecisionLink() => (string) null;

      public override ImageIdentifier GetDecisionImageIdentifier() => (ImageIdentifier) null;

      public PolicyDecisionOutcome(bool shouldBeEnforced)
      {
        this.ShouldDecisionBeEnforced = shouldBeEnforced;
      }
    }
  }
}
